/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.service;

import com.bifrost.common.model.ResultModel;
import com.bifrost.entity.*;
import com.bifrost.entity.ProductService;
import com.bifrost.exception.*;
import com.bifrost.model.*;

import java.util.List;
import java.util.Map;

/**
 * 订单相关功能服务
 *
 * @author joewee
 * @version 1.0.0
 * @Date 2017/11/12 22:13
 */
public interface OrderService {
    boolean isValidRequest(OrderRequest request);

    /**
     * 根据request 对象生成order
     *
     * @param request
     * @return
     */
    Order newOrder(OrderRequest request, Customer customer);

    Order newOrder(OrderModel request, Customer customer);

    Order getConfirmOrderData(Order order) throws UnsupportedShippingTypeException,PromotionException,ProductUnavaliableException;

    /**
     * 获取所有订单
     *
     * @param page     page
     * @param pageSize pageSize
     * @param customer customer
     * @param store store
     * @param status status
     * @param isGetNotComment 是否被用作获取待评价订单
     * @return List
     */
    public List<OrderResult> getOrders(Integer page, Integer pageSize, Customer customer, MerchantStore store, String status, boolean isGetNotComment);

    /**
     * 创建订单编号
     *
     * @return 编号
     */
    @Deprecated
    String generateOrderNumber(Long customer);

    /**
     * 是否有效的订单
     *
     * @param order
     * @return
     */
    boolean isValidOrder(OrderModel order);

    /**
     * 是否有效的订单类型
     * @param orderType
     * @return
     */
    boolean isValidOrderType(String orderType);

    /**
     * 保存订单
     *
     * @param order 订单
     * @return 订单
     */
    Order save(Order order);

    /**
     * 保存订单
     *
     * @param order      订单
     * @param priceOrder 是否重新计价
     * @return 订单
     */
    Order save(Order order, boolean priceOrder) throws PricingException;

    /**
     * 转换成前端可显示的model
     *
     * @param order 订单
     * @return OrderModel
     */
    OrderModel convertToOrderModel(Order order);

    /**
     * 转换成前端可显示的订单基本信息
     *
     * @param order 订单
     * @return OrderModel
     */
    OrderBaseInfo convertToOrderBaseInfo(Order order);

    /**
     * 更加订单id查询订单
     *
     * @param id
     * @return 订单
     */
    Order findOrderById(Long id);

    /**
     * 查询订单
     *
     * @param id       id
     * @param customer customer
     * @return 订单
     */
    Order findOrderByIdAndCustomer(Long id, Customer customer);

    /**
     * 获取不同订单状态数量
     *
     * @param customer
     * @return Map
     */
    Map countStatus(Customer customer, MerchantStore store);

    /**
     * 修改订单状态
     *
     * @param orderId
     * @param status
     * @return 订单
     */
    Integer updateStatus(Long orderId, String status);

    /**
     * 修改订单状态,发货状态
     *
     * @param orderId
     * @param status
     * @param shippingStatus
     * @return 订单
     */
    Integer updateStatus(Long orderId, String status, String shippingStatus);

    boolean serviceIsAvailable(ProductService service, MerchantStore shop);

    boolean canServiceForOrder(Order order);

    /**
     * 检查所有商品是否同个门店
     *
     * @param request
     * @return
     */
    MerchantStore allInOneStore(OrderRequest request);

    /**
     * 检查订单中所有商品是否同个门店
     *
     * @param order
     * @return
     */
    public MerchantStore allInOneStore(Order order);

    /**
     * 为订单增加描述
     *
     * @param order
     * @return
     */
    void describeOrder(Order order);

    /**
     * 更新订单外部交易号用于微信支付
     *
     * @param order
     */
    void updateOutTradeNo(Order order);

    /**
     * 根据外部交易号查找订单
     *
     * @param outTradeNo
     * @return
     */
    Order findOrderByOutTradeNo(String outTradeNo);

    /**
     * 取消订单
     *
     * @param customer customer
     * @param orderId  orderId
     * @param reason   取消原因
     * @return
     */
    void cancel(Customer customer, Long orderId, String reason) throws CancelOrderException;

    /**
     * 筛选提供服务的门店
     *
     * @param request
     * @return
     */
    List getStores(OrderRequest request);

    /**
     * 查询所有未支付订单
     *
     * @return
     */
    List<Order> findAllUnpaidOrders();

    /**
     * 统计订单产生的积分
     *
     * @param order order
     * @return
     */
    Integer countBonusPoints(Order order);

    /**
     * 确认收货
     *
     * @param customer customer
     * @param orderId  orderId
     * @param code
     * @return
     */
    ResultModel confirmReceived(Customer customer, Long orderId, String code);



    List<Order> hasRefundVaildOrder(Order order);

    /**
     * 返回详细收货地址
     *
     * @param order order
     * @return
     */
    String getAddrDetail(Order order);

    /**
     * 获取订单详情
     *
     * @param order
     * @return
     */
    Map orderDetails(Order order);

    /**
     * 获取订单概览信息
     *
     * @param order
     * @return
     */
    OrderResult orderOverview(Order order);

    /**
     * 获取订单状态描述
     *
     * @param order
     * @return
     */
    String getStatusDesc(Order order);

    /**
     * 获取不同状态所有订单
     *
     * @param status
     * @return
     */
    List<Order> findAllByStatus(String status);

    /**
     * 15天自动收货
     *
     */
    public void autoConfirmReceive();

    /**
     * 获取所有未评价订单
     *
     * @return
     */
    public List<Order> findAllNotCommentOrder();

    /**
     * 确认订单信息
     * @param order
     * @return
     */
    int confirmOrder(Order order) throws ConfirmCanceledOrderException;
    /**
     *
     * @param customer
     * @param orderId
     * @param reason
     */
    void cancelUnpaidOrder(Customer customer, Long orderId,String reason) throws CancelOrderException;

    /**
     * 订单退款
     * @param customer
     * @param orderId
     * @return
     *//*
    boolean refund(Customer customer, Long orderId);
    *//**
     * 订单退款
     * @param order
     * @return
     *//*
    boolean refund(Order order);*/
    /**
     * 订单相关回滚操作
     * @param orederId
     */
    void rollbackByOrder(Long   orederId ) throws RollbackBonuspointsException, BonusPointsNotEnoughException;
    /**
     * 订单相关回滚操作
     * @param oreder
     */
    void rollback(Order  oreder ) throws RollbackBonuspointsException, BonusPointsNotEnoughException;
    /**
     * 售后单相关回滚操作
     * @param orederReturnId
     * @return
     */
    void rollbackByOrderReturn(Long  orederReturnId) throws RollbackBonuspointsException, BonusPointsNotEnoughException;


    /**
     * 售后单相关回滚操作
     * @param orederReturn
     * @return
     */
    void rollback(OrderReturn orederReturn) throws RollbackBonuspointsException, BonusPointsNotEnoughException;

    /**
     * 构建积分消息
     * @param orderId
     * @param loyaltyNo
     * @return
     */
    Map buildBonusponitsMsgMapByOrder(Long orderId, String loyaltyNo);

    String determineTransNumber(String storeCode, TransactionSendLog.Type type, Long id);

    Order newCouponOrder(Coupon coupon, Integer quantity, Customer user, String payType);

    void handleCouponOrder(Order order);

    void finishOrder(Order order);

    void cancelUnpaidCouponOrder(Customer customer, Long orderId, String format) throws CancelOrderException;
}
